grammar Cal;

prog: stat+;  //一个程序由至少一条语句组成

/*为了以后的运算的方便性，我们需要给每一步规则打上标签，标签以”#”开头，出现在每一条规则的右边。打上标签后，antlr会为每一个规则都生成一个事件*/

stat: ID '=' expr ';' #Assign //变量赋值语句
| 'print' '(' expr ')' ';' #printExpr   //输出语句
;

expr: expr op=('*'|'/') expr #MulDiv  //表达式可以是表达式之间乘除
  | expr op=('+'|'-') expr #AddSub  //表达式可以是表达式之间加减
  | NUM #NUM    //表达式可以是一个数字
  | ID #ID  //表达式可以是一个变脸
  | '(' expr ')' #parens    //表达式可以被括号括起来
  ;

MUL:'*';
DIV:'/';
ADD:'+';
SUB:'-';

ID: [a-zA-Z][a-zA-Z0-9]*; //变量可以是数字和字母，但必须以字母开头

//负数必须要用"()"括起来
NUM: [0-9]+   //正整数
  | '(' '-' [0-9]+ ')'  //负整数
| [0-9]+'.'[0-9]+   //正浮点数
| '(' '-' [0-9]+'.'[0-9]+ ')'   //负浮点数
;

WS: [ \t\r\n] -> skip;    //跳过空格、制表符、回车、换行